This page last changed on Nov 17, 2004 by casey.

XWork特殊语言特性

XWork基于OGNL并增加的最大功能是支持值栈. OGNL假定只有一个"根(root)", 而XWork值栈的概念支持多个"根".

例如, 假设我们使用标准OGNL(不用XWork), 在OgnlContext表中有两个对象: "foo" -> foo和"bar" -> bar, 并且foo被设置为对象. 下列代码描述OGNL如何处理下列三种情况:
#foo.blah // returns foo.getBlah()
#bar.blah // returns bar.getBlah()
blah      // returns foo.getBlah() because foo is the root

这意味着OGNL允许上下文中包含多个对象, 但除非你要访问的对象是根, 其他访问必须加上名空间如, @bar. 现在我们来讨论XWork的一点区别…

在XWork中, 整个值栈是上下文中的根对象. 但如果你向从栈中获取对象或是用它们的属性, 你并不需要针对值栈编写表达式(如: peek().blah), XWork有一个特殊的OGNL PropertyAccessor它将自动搜索整个值栈(自上而下)知道找到具有你要查找的属性的对象为止.

例如, 假设栈中有两个对象: Animal和Person. 来个对象都有"name"属性, Animal有一个"species"属性, Person有一个"salary"属性. Animal在栈顶, Person在它下面. 下面的代码片断有助于你了解会发生什么:

species    // call to animal.getSpecies()
salary     // call to person.getSalary()
name       // call to animal.getName() because animal is on the top

在最后一个例子中, 两个对象都有name属性, 因此返回了animal的name. 通常这就是期望的效果, 但有时你需要使用低层对象的属性. 为此, XWork支持值栈索引. 你仅需要编写:

[0].name   // call to animal.getName()
[1].name   // call to person.getName()

访问静态属性

OGNL支持对静态方法和属性的访问. 正如OGNL文档指出的, 可以使用下列代码显式调用静态内容:
@some.package.ClassName@FOO_PROPERTY
@some.package.ClassName@someMethod()

然而, XWork不需要指定活动类的完整包名而是用"vs"前缀:

@vs@FOO_PROPERTY
@vs@someMethod()

@vs1@FOO_PROPERTY
@vs1@someMethod()

@vs2@BAR_PROPERTY
@vs2@someOtherMethod()

"vs"就是"value stack". 需要注意的是如果你使用"vs"而不指定类名, 将使用栈顶对象类. 如果你在"vs"后增加数字, 将使用栈中更低层的对象.

与WebWork 1.x表达式语言的区别

除了上面的例子和描述以外, 还有几个主要区别. 最大的区别是属性不再使用'/'访问而是用'.'. 另外, 不再使用".."向下遍历值栈, 目前使用"[n]", n是一个数字. 最后, 在WebWork 1.x中可以使用"@foo"访问特殊命名对象, 但现在特殊变量使用"#foo"访问. 无论如何, 最重要的是"#foo"不能访问请求属性. 因为XWork不仅是为Web而创建, 因此没有"请求属性"的概念, 因此"#foo"仅仅是请求OgnlContext中非根对象的表达式.
Old ExpressionNew Expression
foo/blahfoo.blah
foo/someMethod()foo.someMethod()
../bar/blah[1].bar.blah
@baz不直接支持1, 但#baz与之类似
.top or [0]

WebWork的特殊命名对象

名字
#parameters['foo'] or #parameters.foorequest parameter ['foo'] (request.getParameter())
#request['foo'] or #request.foorequest attribute ['foo'] (request.getAttribute())
#session['foo'] or #session.foosession attribute 'foo'
#application['foo'] or #application.fooServletContext attributes 'foo'
#attr['foo'] or #attr.fooAccess to PageContext if available, otherwise searches request/session/application respectively
Document generated by Confluence on Dec 14, 2004 16:36